# app.py
import streamlit as st
import pandas as pd
import plotly.express as px
from data_pipeline import fetch_movies, process_data, save_to_db, create_mock_data
from config import TMDB_API_KEY


def main():
    # 页面配置（必须在第一个st命令之前）
    st.set_page_config(
        page_title="电影数据分析系统",
        page_icon="🎬",
        layout="wide",
        initial_sidebar_state="expanded"
    )

    st.title("🎬 电影数据分析系统")

    # 侧边栏信息
    with st.sidebar:
        st.header("关于本项目")
        st.markdown("""
        - **数据来源**: TMDB API
        - **技术栈**: Python, Streamlit, Pandas, Plotly
        - **功能**: 实时数据获取、多维度分析、交互可视化
        """)
        st.divider()
        st.caption("开发者: Python数据分析项目")

    # 在页面顶部，创建选项卡
    tab1, tab2, tab3 = st.tabs(["📊 数据总览", "🔍 深度分析", "📈 年度趋势"])

    # 测试按钮：获取并显示数据
    if st.button("🚀 获取电影数据", type="primary"):
        with st.spinner('正在获取数据...'):
            try:
                # 先尝试获取真实数据
                df = fetch_movies(TMDB_API_KEY)
                if not df.empty:
                    st.success("✅ 成功获取TMDB实时数据！")
                    data_source = "API实时数据"
                else:
                    st.warning("⚠️ API返回空数据，使用模拟数据进行演示")
                    df = create_mock_data()
                    data_source = "模拟数据"
            except Exception as e:
                st.warning(f"⚠️ 连接异常，使用模拟数据: {str(e)[:50]}...")
                df = create_mock_data()
                data_source = "模拟数据"

            processed_df = process_data(df)
            save_to_db(processed_df)
            st.session_state.movie_df = processed_df
            st.session_state.data_source = data_source
            st.success(f"🎉 成功加载 {len(processed_df)} 部电影数据 ({data_source})")

    # 显示数据来源提示
    if 'data_source' in st.session_state:
        if st.session_state.data_source == "模拟数据":
            st.info("🔶 当前使用模拟数据进行演示，部分功能可能受限")
        else:
            st.success("🔷 当前使用TMDB实时数据")

    # 选项卡内容
    with tab1:
        st.header("电影数据总览")
        if 'movie_df' not in st.session_state:
            st.info("请先点击【🚀 获取电影数据】按钮加载数据。")
        else:
            df = st.session_state.movie_df
            # 显示选择的列
            display_columns = ['title', 'release_date', 'popularity', 'vote_average', 'vote_count']
            available_columns = [col for col in display_columns if col in df.columns]

            st.dataframe(df[available_columns].head(10))

            # 图表1：评分排行榜
            st.subheader("🎯 评分最高的Top10电影")
            if 'vote_average' in df.columns and 'title' in df.columns:
                top10_movies = df.nlargest(10, 'vote_average')
                fig1 = px.bar(top10_movies, x='vote_average', y='title', orientation='h')
                st.plotly_chart(fig1, use_container_width=True)
            else:
                st.warning("缺少评分或标题数据")

            # 图表2：流行度 vs 评分 散点图
            st.subheader("📈 电影流行度与评分关系")
            if all(col in df.columns for col in ['popularity', 'vote_average', 'title']):
                fig2 = px.scatter(df, x='popularity', y='vote_average', hover_data=['title'])
                st.plotly_chart(fig2, use_container_width=True)
            else:
                st.warning("缺少流行度或评分数据")

    with tab2:
        st.header("深度分析")
        if 'movie_df' not in st.session_state:
            st.info("请先点击【🚀 获取电影数据】按钮加载数据。")
        else:
            df = st.session_state.movie_df
            st.subheader("评分分布情况")
            if 'vote_average' in df.columns:
                fig_score_dist = px.histogram(df, x='vote_average', nbins=20,
                                              title='电影评分分布直方图')
                st.plotly_chart(fig_score_dist, use_container_width=True)

                # 动态计算评分范围
                avg_min, avg_max = df['vote_average'].min(), df['vote_average'].max()
                st.caption(f"✅ 评分范围: {avg_min:.1f} - {avg_max:.1f} 分")
            else:
                st.warning("缺少评分数据")

            # 评分与流行度相关性分析
            st.subheader("评分与流行度相关性")
            if all(col in df.columns for col in ['vote_average', 'popularity']):
                correlation = df['vote_average'].corr(df['popularity'])
                st.metric("相关系数", f"{correlation:.3f}")
                # 解释相关性
                if correlation > 0.5:
                    st.caption("✅ 强正相关：评分高的电影往往也更流行")
                elif correlation > 0.2:
                    st.caption("✅ 中等正相关：评分和流行度有一定关联")
                else:
                    st.caption("✅ 弱相关：评分和流行度关系不大")
            else:
                st.warning("缺少评分或流行度数据")

    with tab3:
        st.header("年度趋势分析")
        if 'movie_df' not in st.session_state:
            st.info("请先点击【🚀 获取电影数据】按钮加载数据。")
        else:
            df = st.session_state.movie_df

            # 年度电影产量趋势
            st.subheader("年度电影产量趋势")
            if 'release_date' in df.columns:
                df_year = df[df['release_date'] != '未知'].copy()
                if not df_year.empty:
                    try:
                        df_year['year'] = pd.to_datetime(df_year['release_date']).dt.year
                        yearly_count = df_year['year'].value_counts().sort_index()
                        fig_year = px.line(x=yearly_count.index, y=yearly_count.values,
                                           title='历年电影产量趋势',
                                           labels={'x': '年份', 'y': '电影数量'})
                        st.plotly_chart(fig_year, use_container_width=True)
                    except Exception as e:
                        st.warning(f"日期处理错误: {e}")
                else:
                    st.warning("没有有效的发布日期数据")
            else:
                st.warning("缺少发布日期数据")

            # "叫好"还是"叫座"？
            st.subheader("“叫好”还是“叫座”？")
            if all(col in df.columns for col in ['vote_count', 'vote_average']):
                df_vote = df.copy()
                df_vote['vote_level'] = ['高投票数' if x > df_vote['vote_count'].median() else '低投票数' for x in
                                         df_vote['vote_count']]

                fig_vote = px.box(df_vote, x='vote_level', y='vote_average',
                                  title='不同投票数级别的评分分布')
                st.plotly_chart(fig_vote, use_container_width=True)

                # 计算中位数差异
                high_median = df_vote[df_vote['vote_level'] == '高投票数']['vote_average'].median()
                low_median = df_vote[df_vote['vote_level'] == '低投票数']['vote_average'].median()
                st.caption(f"✅ 高投票数电影中位数: {high_median:.1f}分，低投票数: {low_median:.1f}分")
            else:
                st.warning("缺少投票数或评分数据")


if __name__ == "__main__":
    main()